#!/usr/bin/python
# -*- coding: utf-8 -*-
# File: collection.py
# Author: Tomás Vírseda
# License: GPL v3
# Description: Collection operations

import datetime

from rdflib import URIRef
import gtk

from vazaarlib.utils import get_logger
from vazaarlib.namespaces import NIE

class CollectionView():
    def __init__(self, gui):
        self.gui = gui
        self.log = get_logger('Collection')
        self.gui.frontend['col-container'] = self.gui.glade.widgets.get_widget("cntCollection")
        self.gui.frontend['col-dlgdelcol'] = self.gui.glade.widgets.get_widget("dlgDeleteCollection")
        self.gui.frontend['col-bdelcancel'] = self.gui.glade.widgets.get_widget("btnDelColCancel")
        self.gui.frontend['col-bdelallcols'] = self.gui.glade.widgets.get_widget("btnDelAllCols")
        self.gui.frontend['col-bdelonlycol'] = self.gui.glade.widgets.get_widget("btnDelOnlyCol")

        self.gui.frontend['col-bdelcancel'].connect('clicked', self.cancel_operation)
        self.gui.frontend['col-bdelallcols'].connect('clicked', self.delete_col_and_resources)
        self.gui.frontend['col-bdelonlycol'].connect('clicked', self.delete_collection)


        self.update_collection_view()
        self.popup = self.create_resources_popup()
        self.operation = None
        self.selected = None

    def get_selected_collection(self):
        selection = self.treeview.get_selection()
        model, paths = selection.get_selected_rows()
        path = paths[0]
        iter = model.get_iter_from_string(str(path[0]))

        return model.get_value(iter, 0)


    def cancel_operation(self, *args):
        self.gui.frontend['col-dlgdelcol'].hide_all()

    def edit_selected_collection(self, *args):
        col = self.get_selected_collection()
        self.gui.editor.update_id(col)
        self.gui.editor.show_dialog()

    def delete_col_and_resources(self, *args):
        col = self.get_selected_collection()
        resources = self.gui.ask.resources_in_collection(col)
        self.target_list = []
        self.target_list.append(col)
        self.target_list += resources
        self.gui.app.vstore.delete_resources(self.target_list)
        icon = self.gui.icons.get_icon_by_name('Collection-delete.svg', 128, 128)
        self.gui.actions.notify("Collection deleted", "<big>The collection and all its resources were <b>deleted</b></big>", icon)
        self.gui.frontend['col-dlgdelcol'].hide_all()
        self.gui.actions.update_gui()

    def delete_collection(self, *args):
        col = self.get_selected_collection()
        self.target_list = []
        self.target_list.append(col)
        self.gui.app.vstore.delete_resources(self.target_list)
        #icon = self.gui.icons.get_icon_by_name(PIMO['Collection'], 32, 32)
        #icon = self.gui.widget.render_icon(gtk.STOCK_DELETE, gtk.ICON_SIZE_DIALOG)
        icon = self.gui.icons.get_icon_by_name('Collection-delete.svg', 128, 128)
        self.gui.actions.notify("Collection deleted", "<big>The collection was <b>deleted</b> but all its resources have been <b>kept</b></big>", icon)
        self.gui.frontend['col-dlgdelcol'].hide_all()
        self.gui.actions.update_gui()


    def delete_selected_collection(self, *args):
        self.gui.frontend['col-dlgdelcol'].show_all()



    def show_window(self, operation=''):
        self.operation = operation
        self.update_collection_view()
        if operation == 'add_to_collection':
            pass


    def create_resources_popup(self):
        menu = gtk.Menu()
        try:
            # add menu
            mnuitem = gtk.ImageMenuItem('Add new collection')
            mnuitem.connect('activate', self.gui.actions.add_new_collection)
            icon = self.gui.widget.render_icon(gtk.STOCK_ADD, gtk.ICON_SIZE_BUTTON)
            mnuitem.set_image(gtk.image_new_from_pixbuf(icon))
            menu.append(mnuitem)

            # edit menu
            mnuitem = gtk.ImageMenuItem('Edit selected collection')
            mnuitem.connect('activate', self.edit_selected_collection)
            icon = self.gui.widget.render_icon(gtk.STOCK_EDIT, gtk.ICON_SIZE_BUTTON)
            mnuitem.set_image(gtk.image_new_from_pixbuf(icon))
            menu.append(mnuitem)

            mnuitem = gtk.ImageMenuItem('Delete selected collection')
            mnuitem.connect('activate', self.delete_selected_collection)
            icon = self.gui.widget.render_icon(gtk.STOCK_DELETE, gtk.ICON_SIZE_BUTTON)
            mnuitem.set_image(gtk.image_new_from_pixbuf(icon))
            menu.append(mnuitem)

            """
            mnuitem = gtk.SeparatorMenuItem()
            menu.append(mnuitem)

            mnuitem = gtk.ImageMenuItem('Export collection(s)')
            mnuitem.connect('activate', self.export_selected)
            icon = self.gui.widget.render_icon(gtk.STOCK_DELETE, gtk.ICON_SIZE_BUTTON)
            mnuitem.set_image(gtk.image_new_from_pixbuf(icon))
            menu.append(mnuitem)
            """
            menu.show_all()
            return menu
        except Exception, error:
            print error

    def hide_window(self, *args):
        self.gui.frontend['col-window'].hide_all()

    def update_collection_view(self):
        query = """
                PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
                PREFIX pimo: <http://www.semanticdesktop.org/ontologies/pimo/>
                PREFIX nie: <http://www.semanticdesktop.org/ontologies/nie/>

                SELECT ?id ?title
                WHERE
                {
                    ?id rdf:type pimo:Collection .
                    ?id nie:title ?title .
                }
                ORDER BY ASC(?title)
                """

        result = self.gui.ask.this(query)
        icon = self.gui.widget.render_icon(gtk.STOCK_ADD, gtk.ICON_SIZE_DIALOG)
        model = gtk.ListStore(str, gtk.gdk.Pixbuf, str)
        icon = self.gui.icons.get_icon_by_name('unlinked.svg', 48)
        model.append(('notelementof', icon, 'Unlinked resources'))
        icon = self.gui.icons.get_icon_by_name('linked.svg', 48)
        for (id, title) in result.selected:
            #print id, title
            model.append((id, icon, title))
        #self.treeview = gtk.TreeView()
        #self.treeview.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH)
        self.treeview = gtk.TreeView(model)
        #self.treeview.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH)
        #self.treeview.set_model(model)
        self.treeview.set_headers_visible(False)
        self.treeview.connect('row-activated', self.row_activated)
        self.treeview.connect('button-press-event', self.popup_menu)
        #self.treeview.connect('cursor-changed', self.cursor_changed)

        selection = self.treeview.get_selection()
        selection.set_mode(gtk.SELECTION_MULTIPLE)
        selection.unselect_all()

        renderer = gtk.CellRendererText()
        column = gtk.TreeViewColumn('id', renderer, text=0)
        column.set_visible(False)
        self.treeview.append_column(column)

        renderer = gtk.CellRendererPixbuf()
        column = gtk.TreeViewColumn('', renderer, pixbuf=1)
        self.treeview.append_column(column)

        renderer = gtk.CellRendererText()
        #renderer.connect('edited', self.cell_edited_callback, model)
        #renderer.connect('editing-canceled', self.cell_editing_canceled, model)
        #renderer.set_property('editable', True)
        column = gtk.TreeViewColumn('Title', renderer, text=2)
        self.treeview.append_column(column)

        self.treeview.show_all()
        container = gtk.ScrolledWindow()
        container.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        container.set_shadow_type(gtk.SHADOW_OUT)
        container.add(self.treeview)
        container.show_all()

        old = self.gui.frontend['col-container'].get_children()
        if old:
            self.gui.frontend['col-container'].remove(old[0])

        self.gui.frontend['col-container'].add(container)
        self.gui.frontend['col-container'].show_all()

    def update_collection_name(self):
        pass

    def row_activated(self, treeview, paths, column):
        t1 = datetime.datetime.now()
        model = treeview.get_model()
        path = str(paths[0])
        iter = model.get_iter_from_string(path)
        col = model.get_value(iter, 0)
        name = model.get_value(iter, 2)

        if col == 'notelementof':
            resources = self.gui.ask.unlinked_resources()
        else:
            resources = self.gui.ask.resources_in_collection(col)

        self.gui.frontend['view']['selected'] = resources
        t2 = datetime.datetime.now()
        tf1 = t2 - t1
        t1 = datetime.datetime.now()
        self.gui.actions.update_gui(filterdate=False)
        t2 = datetime.datetime.now()
        tf2 = t2 - t1
        text = "Query collection <b>%s</b> in <i>%s secs</i>\t\t<b>GUI</b>: <i>%s secs</i>" % (name, tf1, tf2)
        self.gui.statusbar.set_text(text)
        #self.gui.ask.describe(col)


    def cursor_changed(self, treeview, *data):
        paths, column = treeview.get_cursor()
        model = treeview.get_model()
        path = str(paths[0])
        #print path
        iter = model.get_iter_from_string(path[0])
        #print iter
        col = model.get_value(iter, 0)
        #print col
        resources = self.gui.ask.resources_in_collection(col)
        #print type(resources)
        self.gui.frontend['view']['selected'] = resources
        self.gui.actions.update_gui()


    def cell_editing_canceled(self, cell, model):
        pass #print "editing canceled"

    def cell_edited_callback(self, cellrenderertext, path, new_text, model):
        iter = model.get_iter_from_string(str(path))
        id = model.get_value(iter, 0)
        if id == '-':
            title = new_text.decode('iso-8859-15')
            self.gui.app.vstore.create_new_collection(title)
        self.update_collection_view()

    def get_target(self, model, path, iter):
        # Add to source target list
        id = model.get_value(iter, 0)
        self.selected.append(id)

    def on_ok_callback(self, widget):
        if self.operation == 'add_to_collection':
            self.selected = []
            selection = self.treeview.get_selection()
            selection.selected_foreach(self.get_target)
            collections = self.selected
            resources = self.gui.frontend['target']
            for idres in resources:
                for idcol in collections:
                    #FIXME: don't access bbdd directly. Use VStore
                    # because vazaar must be notified of all changes in
                    # every single resource.
                    if idcol != idres:
                        self.gui.app.store.add_triple(URIRef(idcol), NIE['hasLogicalPart'], URIRef(idres))
        self.gui.actions.update_gui()
        self.hide_window()

    def on_help_callback(self, widget):
        self.log.debug("on_ok_callback: not implemented")


    def toggle_view(self):
        if self.gui.frontend['sh-btntcol'].get_active():
            self.gui.frontend['sh-collection'].hide_all()
        else:
            self.update_collection_view()
            self.gui.frontend['sh-collection'].show_all()

    def popup_menu(self, treeview, event):
        if event.button == 3:
            x = int(event.x)
            y = int(event.y)
            time = event.time
            pthinfo = treeview.get_path_at_pos(x, y)
            if pthinfo is not None:
                path, col, cellx, celly = pthinfo
                treeview.grab_focus()
                treeview.set_cursor( path, col, 0)
                self.popup.popup( None, None, None, event.button, time)
            return 1

    def toggled_callback(self, cell, path, model=None, col_num=0):
        iter = model.get_iter(path)
        model.set_value(iter, 3, not cell.get_active())

    def update_selected_collections(self):
        self.selected = []
        selection = self.treeview.get_selection()
        selection.selected_foreach(self.get_target)
        self.gui.frontend['target-col'] = self.selected

    def export_selected(self, *args):
        print self.log.info('Not implemented')
